package ACEbrickBreaker;

/**
 * <p>Title: WriteXMLscoresFile</p>
 * <p>Description: WriteXMLscoresFile
 *	This class writes data to an XML file. At the end of a game (when either the player loses all their lives, or the player has destroyed all the bricks) the player name, time, and score is recorded in the XML file. 
 * * @author Caitlin Finn
 * @email caitlin.finn@my.uwrf.edu
 * @author Erin McNeil
 * @email erin.mcneil@my.uwrf.edu
 * @author Andrew Juranek
 * @email andrew.juranek@my.uwrf.edu
 * @date December 10th 2012
 */
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class WriteXMLscoresFile {
	private String pname;
	private String pscore;
	private String ptime;
	private final ArrayList<Score> scoresArray;

	/**
	 * call CopyOfWriteXMLFile from main with the player's name, score and time
	 * 
	 * @param pname
	 * @param pscore
	 * @param ptime
	 */
	public WriteXMLscoresFile(String pname, String pscore, String ptime) {
		this.pname = pname;
		this.pscore = pscore;
		this.ptime = ptime;

		// read the current high scores from xml file and build a new XML
		// document
		File fXmlFile = new File("highScoreCurrent.xml");
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = null;
		try {
			dBuilder = dbFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		Document doc = null;
		try {
			doc = dBuilder.parse(fXmlFile);
		} catch (SAXException | IOException e) {
			e.printStackTrace();
		}
		doc.getDocumentElement().normalize();

		// get the nodes of the XML file and store the values in an ArrayList of
		// Score objects
		NodeList nList = doc.getElementsByTagName("Player");
		scoresArray = new ArrayList<Score>();
		for (int temp = 0; temp < nList.getLength(); temp++) {

			Node nNode = nList.item(temp);
			if (nNode.getNodeType() == Node.ELEMENT_NODE) {

				Element eElement = (Element) nNode;
				Score scoreEntry = new Score(getTagValue("name", eElement),
						Integer.parseInt(getTagValue("score", eElement)),
						getTagValue("time", eElement));
				// add the current scores to the array list of scores read in
				// from
				// the XML file
				scoresArray.add(scoreEntry);

			}
		}
		// // add the new scores to the array list of scores read in from
		// the XML file
		Score newScoreEntry = new Score(pname, Integer.parseInt(pscore), ptime);
		scoresArray.add(newScoreEntry);

		// sort the high scores list by score
		Collections.sort(scoresArray, new Comparator<Score>() {
			@Override
			public int compare(Score p1, Score p2) {
				return p2.getScore() - p1.getScore();
			}

		});

		// write the new list of high scores after the addition of the last
		// score to the old XML file
		try {

			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			// root elements

			doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("High_Scores");
			doc.appendChild(rootElement);

			for (int i = 0; i < scoresArray.size(); i++) {

				// staff elements
				Element Player = doc.createElement("Player");
				rootElement.appendChild(Player);

				// name elements
				Element name = doc.createElement("name");
				name.appendChild(doc.createTextNode(scoresArray.get(i)
						.getName()));
				Player.appendChild(name);

				// score elements
				Element score = doc.createElement("score");
				score.appendChild(doc.createTextNode(Integer
						.toString(scoresArray.get(i).getScore())));
				Player.appendChild(score);

				// nickname elements
				Element time = doc.createElement("time");
				time.appendChild(doc.createTextNode(scoresArray.get(i)
						.getTime()));
				Player.appendChild(time);

			}

			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();

			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(
					"highScoreCurrent.xml"));

			transformer.transform(source, result);

		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (TransformerException tfe) {
			tfe.printStackTrace();
		}

	}

	/**
	 * gets the player name
	 * 
	 * @return pname
	 */
	public String getPname() {
		return pname;
	}

	/**
	 * sets the player name
	 * 
	 * @param pname
	 */
	public void setPname(String pname) {
		this.pname = pname;
	}

	/**
	 * gets the player's score
	 * 
	 * @return pscore
	 */
	public String getPscore() {
		return pscore;
	}

	/**
	 * sets the player's score
	 * 
	 * @param pscore
	 */
	public void setPscore(String pscore) {
		this.pscore = pscore;
	}

	/**
	 * gets the player's time
	 * 
	 * @return ptime
	 */
	public String getPtime() {
		return ptime;
	}

	/**
	 * sets the player's time
	 * 
	 * @param ptime
	 */
	public void setPtime(String ptime) {
		this.ptime = ptime;
	}

	private static String getTagValue(String sTag, Element eElement) {
		NodeList nlList = eElement.getElementsByTagName(sTag).item(0)
				.getChildNodes();

		Node nValue = nlList.item(0);

		return nValue.getNodeValue();
	}
}
